package com.situ.mall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.situ.mall.pojo.entity.product.Category;
import com.situ.mall.product.pojo.vo.Category13VO;
import com.situ.mall.product.pojo.vo.Category23VO;
import com.situ.mall.product.pojo.vo.CategoryVO;
import com.situ.mall.product.mapper.CategoryMapper;
import com.situ.mall.product.service.ICategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品分类 服务实现类
 * </p>
 *
 * @author Sun Huijuan
 * @since 2024-10-09
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {
	
	@Autowired
	private CategoryMapper categoryMapper;
	
//@Cacheable(value = {"category","product"})一下子存储到多个
//	@Cacheable(value = "category",key = "'selectCategoryTree'")
//	第一次访问查询数据库，返回数据存到Redis命名为selectCategoryTree，再次访问直接从缓存中取，不走实现方法。
	@Cacheable(value = "category",key = "#root.methodName")
//	@Override
	public List<CategoryVO> selectCategoryTree1() {
		//1.查询所有分类，返回list集合
		QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
		queryWrapper.orderByAsc("order_num");
		List<Category> categoryList = categoryMapper.selectList(queryWrapper);
		List<CategoryVO> categoryVOList = new ArrayList<>();
		categoryList.forEach(category -> {
			CategoryVO categoryVO = new CategoryVO();
			BeanUtils.copyProperties(category, categoryVO);
			categoryVOList.add(categoryVO);
		});
		//2 遍历所有分类list集合，通过条件 parentid=0得到所有一级分类
		List<CategoryVO> oneCategoryVOList =
				categoryVOList.stream()
						.filter(categoryVO -> categoryVO.getParentId().longValue() == 0)
						.collect(Collectors.toList());
		
		//3 遍历所有一级分类list集合，条件判断： id = parentid，得到一级下面二级分类
		oneCategoryVOList.forEach(categoryVO -> {
			List<CategoryVO> twoCategoryList =
					categoryVOList.stream()
							.filter(item -> item.getParentId().longValue() == categoryVO.getId())
							.collect(Collectors.toList());
			//把二级分类封装到一级分类里面
			categoryVO.setChildren(twoCategoryList);
			
			//4 遍历所有二级分类， 条件判断： id = parentid，得到二级下面三级分类
			twoCategoryList.forEach(twoCategory -> {
				List<CategoryVO> threeCategoryList =
						categoryVOList.stream()
								.filter(item -> item.getParentId() == twoCategory.getId())
								.collect(Collectors.toList());
				//把三级分类封装到二级分类里面
				twoCategory.setChildren(threeCategoryList);
			});
		});
		
		return oneCategoryVOList;
	}
	
	@Cacheable(value = "category",key = "#root.methodName")
	@Override
	public List<CategoryVO> selectCategoryTree() {
		//1.查询所有分类，返回list集合
		QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
		queryWrapper.orderByAsc("order_num");
		List<Category> categoryList = categoryMapper.selectList(queryWrapper);
		List<CategoryVO> categoryVOList = new ArrayList<>();
		categoryList.forEach(category -> {
			CategoryVO categoryVO = new CategoryVO();
			BeanUtils.copyProperties(category, categoryVO);
			categoryVOList.add(categoryVO);
		});
		//递归实现无限级树形结构
		return buildTree(categoryVOList);
	}
	
	//递归实现树形结构
	private List<CategoryVO> buildTree(List<CategoryVO> categoryVOList) {
		List<CategoryVO> treeList=new ArrayList<>();
		if(!CollectionUtils.isEmpty(categoryVOList)){
			for(CategoryVO categoryVO:categoryVOList){
				//递归的入口是parentId=0
				if(categoryVO.getParentId()==0){
					categoryVO.setChildren(buildChildTree(categoryVO,categoryVOList));
					treeList.add(categoryVO);
				}
			}
		}
		return treeList;
	}
	
	/**
	 *
	 * @param categoryVO  要查找的childTree的父亲
	 * @param categoryVOList  所有分类集合
	 * @return
	 */
	private List<CategoryVO> buildChildTree(CategoryVO categoryVO, List<CategoryVO> categoryVOList) {
		List<CategoryVO> childTree=new ArrayList<>();
		if(!CollectionUtils.isEmpty(categoryVOList)){
			for(CategoryVO category:categoryVOList){
				if(category.getParentId().longValue()==categoryVO.getId()){
					//添加孩子的时候，先把孩子的孩子的集合构造出来
					category.setChildren(buildChildTree(category,categoryVOList));
					childTree.add(category);
				}
			}
		}
		return childTree;
	}
	
	
	//多个参数 key = "{#root.methodName, #id, #name}"
	@Cacheable(value = {"category"}, key = "{#root.methodName, #id}")
	@Override
	public List<CategoryVO> selectByParentId(Long id) {
		QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("parent_id",id);
		queryWrapper.orderByAsc("order_num");
		List<Category> categoryList = categoryMapper.selectList(queryWrapper);
		List<CategoryVO> categoryVOList = new ArrayList<>();
		categoryList.forEach(category -> {
			CategoryVO categoryVO = new CategoryVO();
			BeanUtils.copyProperties(category, categoryVO);
			//查找当前的category有没有孩子
			QueryWrapper<Category> countQueryWrapper=new QueryWrapper<>();
			countQueryWrapper.eq("parent_id",category.getId());
			Long count = categoryMapper.selectCount(countQueryWrapper);
			if(count>0){
				categoryVO.setHasChildren(true);
			}else {
				categoryVO.setHasChildren(false);
			}
			categoryVOList.add(categoryVO);
		});
		
		return categoryVOList;
	}
	
	@Override
	public List<Category> selectAllCategory3() {
		List<Category> categoryList = categoryMapper.selectList(null);
		List<Category> category3List = new ArrayList<>();
		categoryList.forEach(category -> {
			Long number=categoryMapper.selectCount(new QueryWrapper<Category>().eq("parent_id",category.getId()));
			if(number==0){
				category3List.add(category);
			}
		});
		return category3List;
	}
	
	@Override
	public List<Category23VO> selectAllCategory23() {
		//1.查询所有分类，返回list集合
		QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("parent_id",0L);
		//一级分类列表
		List<Category> categoryList = categoryMapper.selectList(queryWrapper);
		//二级分类VO列表
		List<Category23VO> twoCategoryList =new ArrayList<>();
		for(Category category:categoryList){
			List<Category> category2List=categoryMapper.selectList(new QueryWrapper<Category>().eq("parent_id",category.getId()));
			for(Category category2:category2List){
				Category23VO category23VO=new Category23VO();
				BeanUtils.copyProperties(category2,category23VO);
				List<Category> category3List=categoryMapper.selectList(new QueryWrapper<Category>().eq("parent_id",category2.getId()));
				category23VO.setColumns(category3List);
				twoCategoryList.add(category23VO);
			}
		}
		return twoCategoryList;
	}
	
	
	
	/**
	 * CacheEvict 失效模式
	 * @Caching 同时进行多种缓存操作
	 * 删除某个分区下所有缓存：@CacheEvict(value = "category", allEntries = true)
	 */
	//@CacheEvict(value = "category", key = "'selectCategoryTree'")
	/*@Caching(evict = {
			@CacheEvict(value = "category", key = "'selectCategoryTree'"),
			@CacheEvict(value = "category", key = "'selectByParentId'")
	})*/
	@CacheEvict(value = "category", allEntries = true)
	@Override
	public void update(Category category) {
		categoryMapper.updateById(category);
	}
	
	@Override
	public List<Category13VO> selectAllCategory13() {
		//1.查询所有分类，返回list集合
		QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("parent_id",0L);
		//一级分类列表
		List<Category> categoryList = categoryMapper.selectList(queryWrapper);
		//一、三级分类列表
		List<Category13VO> category13List =new ArrayList<>();
		for(Category category:categoryList){
			//某一级分类下的二级分类ID列表
			List<Long> category2List=categoryMapper.selectCategory2IdList(category.getId());
				Category13VO category13VO=new Category13VO();
				BeanUtils.copyProperties(category,category13VO);
				List<Category> category3List=categoryMapper.selectList(new QueryWrapper<Category>().in("parent_id",category2List));
				category13VO.setCategory3(category3List);
				category13List.add(category13VO);
		}
		return category13List;
	}
	
	@CacheEvict(value = "category", allEntries = true)
	@Override
	public void deleteById(Long id) {
		categoryMapper.deleteById(id);
	}
	
	@CacheEvict(value = "category", allEntries = true)
	@Override
	public void add(Category category) {
		categoryMapper.insert(category);
	}
}
